import handler, { throttle } from "./tools.js";
export default class Snake {
  constructor() {
    this.body = document.body;
    this.game = document.querySelector(".game");
    this.temp = "";
    this.size = 16 ** 2;
    this.color = "#142334";
    this.numArr = [17, 16];
    this.lastCode = 39;
    this.timer;
    this.food = [1];
  }
  init() {
    this.render();
    this.bindEvent();
  }
  bindEvent() {
    this.body.addEventListener(
      "keyup",
      throttle(this.keyupEvent.bind(this)),
      false
    );
  }
  keyupEvent(ev) {
    let code = ev.keyCode;
    if ([37, 38, 39, 40].includes(code)) {
      this.renderChange(code);
    }
  }
  render() {
    this.renderBack();
    this.renderChange();
  }
  renderChange(code = 39) {
    if (Math.abs(this.lastCode - code) === 2) return; //不能回头
    this.lastCode = code;
    this.timer && clearInterval(this.timer);
    this.timer = setInterval(() => {
      handler[code](this.numArr, this.food); //这里会同时修改 food，在下面就直接渲染了
      let over = this.isOver(code); //因为定时器是异步，需要短路一下
      over || this.renderSnake(this.numArr);
    }, 300);
  }
  isOver(code) {
    let left = code === 37 && this.numArr[0] % 16 === 15;
    let right = code === 39 && this.numArr[0] % 16 === 0;
    let upDown = this.numArr[0] < 0 || this.numArr[0] > this.size;
    let eatSelf = this.numArr.lastIndexOf(this.numArr[0]) !== 0; //蛇身上不止一个[0]号元素，吃到自己
    let over = left || right || upDown || eatSelf;
    if (over) {
      clearInterval(this.timer);
    }
    return over;
  }
  // 把食物并列 一起渲染 concat不改变原数组
  renderSnake(arr = this.numArr) {
    arr = arr.concat(this.food);
    [].forEach.call(this.game.children, (div, index) => {
      arr.includes(index)
        ? (div.style.backgroundColor = this.color)
        : (div.style.backgroundColor = "chocolate");
    });
  }
  renderBack() {
    let s = this.size;
    while (s--) {
      this.temp += `<div></div>`;
    }
    this.game.innerHTML = this.temp;
  }
}
